+2001-01-10 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
+ where sibling == iter
+ (gtk_tree_store_insert_after): handle sibling == iter
+ (gtk_tree_store_prepend): remove stamp checks
+ (gtk_tree_store_insert_before): ditto
+ (gtk_tree_store_append): ditto
+ (gtk_tree_store_get_path): ditto
+ (gtk_tree_store_get_value): ditto
+ (gtk_tree_store_iter_has_child): ditto
+ (gtk_tree_store_iter_n_children): ditto
+ (gtk_tree_store_iter_nth_child): ditto
+ (gtk_tree_store_insert_after): ditto
+ (gtk_tree_store_is_ancestor): ditto
+ (gtk_tree_store_iter_depth): ditto
+ (gtk_tree_store_insert_before): assert that sibling's parent is
+ the same as the passed-in parent
+ (gtk_tree_store_insert_after): assert that sibling's parent is
+ the same as the passed-in parent
+
+
+ * gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
+ function to get the first iterator in a model
+
+ * gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
+ conventionally the "root" in this sense is just NULL afaict.
+
+ * gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
+ where sibling == iter
+ (gtk_list_store_insert_after): handle case where sibling == iter
+
+ * tests/testtreeview.c (run_automated_tests): fairly lame basic
+ automated tests for ListStore, TreeStore
+
+ * gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
+ (gtk_list_store_insert): update tail pointer, and fix it to work
+ (gtk_list_store_insert_before): update tail pointer, and fix it to work
+ (gtk_list_store_append): use tail to be faster
+ (gtk_list_store_prepend): fix it, update tail pointer
+ (gtk_list_store_insert_after): fix it, update tail pointer
+
+ * gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
+ the list
+
2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
+2001-01-10 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
+ where sibling == iter
+ (gtk_tree_store_insert_after): handle sibling == iter
+ (gtk_tree_store_prepend): remove stamp checks
+ (gtk_tree_store_insert_before): ditto
+ (gtk_tree_store_append): ditto
+ (gtk_tree_store_get_path): ditto
+ (gtk_tree_store_get_value): ditto
+ (gtk_tree_store_iter_has_child): ditto
+ (gtk_tree_store_iter_n_children): ditto
+ (gtk_tree_store_iter_nth_child): ditto
+ (gtk_tree_store_insert_after): ditto
+ (gtk_tree_store_is_ancestor): ditto
+ (gtk_tree_store_iter_depth): ditto
+ (gtk_tree_store_insert_before): assert that sibling's parent is
+ the same as the passed-in parent
+ (gtk_tree_store_insert_after): assert that sibling's parent is
+ the same as the passed-in parent
+
+
+ * gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
+ function to get the first iterator in a model
+
+ * gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
+ conventionally the "root" in this sense is just NULL afaict.
+
+ * gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
+ where sibling == iter
+ (gtk_list_store_insert_after): handle case where sibling == iter
+
+ * tests/testtreeview.c (run_automated_tests): fairly lame basic
+ automated tests for ListStore, TreeStore
+
+ * gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
+ (gtk_list_store_insert): update tail pointer, and fix it to work
+ (gtk_list_store_insert_before): update tail pointer, and fix it to work
+ (gtk_list_store_append): use tail to be faster
+ (gtk_list_store_prepend): fix it, update tail pointer
+ (gtk_list_store_insert_after): fix it, update tail pointer
+
+ * gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
+ the list
+
2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
+2001-01-10 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
+ where sibling == iter
+ (gtk_tree_store_insert_after): handle sibling == iter
+ (gtk_tree_store_prepend): remove stamp checks
+ (gtk_tree_store_insert_before): ditto
+ (gtk_tree_store_append): ditto
+ (gtk_tree_store_get_path): ditto
+ (gtk_tree_store_get_value): ditto
+ (gtk_tree_store_iter_has_child): ditto
+ (gtk_tree_store_iter_n_children): ditto
+ (gtk_tree_store_iter_nth_child): ditto
+ (gtk_tree_store_insert_after): ditto
+ (gtk_tree_store_is_ancestor): ditto
+ (gtk_tree_store_iter_depth): ditto
+ (gtk_tree_store_insert_before): assert that sibling's parent is
+ the same as the passed-in parent
+ (gtk_tree_store_insert_after): assert that sibling's parent is
+ the same as the passed-in parent
+
+
+ * gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
+ function to get the first iterator in a model
+
+ * gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
+ conventionally the "root" in this sense is just NULL afaict.
+
+ * gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
+ where sibling == iter
+ (gtk_list_store_insert_after): handle case where sibling == iter
+
+ * tests/testtreeview.c (run_automated_tests): fairly lame basic
+ automated tests for ListStore, TreeStore
+
+ * gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
+ (gtk_list_store_insert): update tail pointer, and fix it to work
+ (gtk_list_store_insert_before): update tail pointer, and fix it to work
+ (gtk_list_store_append): use tail to be faster
+ (gtk_list_store_prepend): fix it, update tail pointer
+ (gtk_list_store_insert_after): fix it, update tail pointer
+
+ * gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
+ the list
+
2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
+2001-01-10 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
+ where sibling == iter
+ (gtk_tree_store_insert_after): handle sibling == iter
+ (gtk_tree_store_prepend): remove stamp checks
+ (gtk_tree_store_insert_before): ditto
+ (gtk_tree_store_append): ditto
+ (gtk_tree_store_get_path): ditto
+ (gtk_tree_store_get_value): ditto
+ (gtk_tree_store_iter_has_child): ditto
+ (gtk_tree_store_iter_n_children): ditto
+ (gtk_tree_store_iter_nth_child): ditto
+ (gtk_tree_store_insert_after): ditto
+ (gtk_tree_store_is_ancestor): ditto
+ (gtk_tree_store_iter_depth): ditto
+ (gtk_tree_store_insert_before): assert that sibling's parent is
+ the same as the passed-in parent
+ (gtk_tree_store_insert_after): assert that sibling's parent is
+ the same as the passed-in parent
+
+
+ * gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
+ function to get the first iterator in a model
+
+ * gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
+ conventionally the "root" in this sense is just NULL afaict.
+
+ * gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
+ where sibling == iter
+ (gtk_list_store_insert_after): handle case where sibling == iter
+
+ * tests/testtreeview.c (run_automated_tests): fairly lame basic
+ automated tests for ListStore, TreeStore
+
+ * gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
+ (gtk_list_store_insert): update tail pointer, and fix it to work
+ (gtk_list_store_insert_before): update tail pointer, and fix it to work
+ (gtk_list_store_append): use tail to be faster
+ (gtk_list_store_prepend): fix it, update tail pointer
+ (gtk_list_store_insert_after): fix it, update tail pointer
+
+ * gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
+ the list
+
2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
+2001-01-10 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
+ where sibling == iter
+ (gtk_tree_store_insert_after): handle sibling == iter
+ (gtk_tree_store_prepend): remove stamp checks
+ (gtk_tree_store_insert_before): ditto
+ (gtk_tree_store_append): ditto
+ (gtk_tree_store_get_path): ditto
+ (gtk_tree_store_get_value): ditto
+ (gtk_tree_store_iter_has_child): ditto
+ (gtk_tree_store_iter_n_children): ditto
+ (gtk_tree_store_iter_nth_child): ditto
+ (gtk_tree_store_insert_after): ditto
+ (gtk_tree_store_is_ancestor): ditto
+ (gtk_tree_store_iter_depth): ditto
+ (gtk_tree_store_insert_before): assert that sibling's parent is
+ the same as the passed-in parent
+ (gtk_tree_store_insert_after): assert that sibling's parent is
+ the same as the passed-in parent
+
+
+ * gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
+ function to get the first iterator in a model
+
+ * gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
+ conventionally the "root" in this sense is just NULL afaict.
+
+ * gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
+ where sibling == iter
+ (gtk_list_store_insert_after): handle case where sibling == iter
+
+ * tests/testtreeview.c (run_automated_tests): fairly lame basic
+ automated tests for ListStore, TreeStore
+
+ * gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
+ (gtk_list_store_insert): update tail pointer, and fix it to work
+ (gtk_list_store_insert_before): update tail pointer, and fix it to work
+ (gtk_list_store_append): use tail to be faster
+ (gtk_list_store_prepend): fix it, update tail pointer
+ (gtk_list_store_insert_after): fix it, update tail pointer
+
+ * gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
+ the list
+
2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
+2001-01-10 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
+ where sibling == iter
+ (gtk_tree_store_insert_after): handle sibling == iter
+ (gtk_tree_store_prepend): remove stamp checks
+ (gtk_tree_store_insert_before): ditto
+ (gtk_tree_store_append): ditto
+ (gtk_tree_store_get_path): ditto
+ (gtk_tree_store_get_value): ditto
+ (gtk_tree_store_iter_has_child): ditto
+ (gtk_tree_store_iter_n_children): ditto
+ (gtk_tree_store_iter_nth_child): ditto
+ (gtk_tree_store_insert_after): ditto
+ (gtk_tree_store_is_ancestor): ditto
+ (gtk_tree_store_iter_depth): ditto
+ (gtk_tree_store_insert_before): assert that sibling's parent is
+ the same as the passed-in parent
+ (gtk_tree_store_insert_after): assert that sibling's parent is
+ the same as the passed-in parent
+
+
+ * gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
+ function to get the first iterator in a model
+
+ * gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
+ conventionally the "root" in this sense is just NULL afaict.
+
+ * gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
+ where sibling == iter
+ (gtk_list_store_insert_after): handle case where sibling == iter
+
+ * tests/testtreeview.c (run_automated_tests): fairly lame basic
+ automated tests for ListStore, TreeStore
+
+ * gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
+ (gtk_list_store_insert): update tail pointer, and fix it to work
+ (gtk_list_store_insert_before): update tail pointer, and fix it to work
+ (gtk_list_store_append): use tail to be faster
+ (gtk_list_store_prepend): fix it, update tail pointer
+ (gtk_list_store_insert_after): fix it, update tail pointer
+
+ * gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
+ the list
+
2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
+2001-01-10 Havoc Pennington <hp@redhat.com>
+
+ * gtk/gtktreestore.c (gtk_tree_store_insert_before): handle case
+ where sibling == iter
+ (gtk_tree_store_insert_after): handle sibling == iter
+ (gtk_tree_store_prepend): remove stamp checks
+ (gtk_tree_store_insert_before): ditto
+ (gtk_tree_store_append): ditto
+ (gtk_tree_store_get_path): ditto
+ (gtk_tree_store_get_value): ditto
+ (gtk_tree_store_iter_has_child): ditto
+ (gtk_tree_store_iter_n_children): ditto
+ (gtk_tree_store_iter_nth_child): ditto
+ (gtk_tree_store_insert_after): ditto
+ (gtk_tree_store_is_ancestor): ditto
+ (gtk_tree_store_iter_depth): ditto
+ (gtk_tree_store_insert_before): assert that sibling's parent is
+ the same as the passed-in parent
+ (gtk_tree_store_insert_after): assert that sibling's parent is
+ the same as the passed-in parent
+
+
+ * gtk/gtktreemodel.c (gtk_tree_model_get_first): new convenience
+ function to get the first iterator in a model
+
+ * gtk/gtktreestore.c (gtk_tree_store_get_root_iter): remove,
+ conventionally the "root" in this sense is just NULL afaict.
+
+ * gtk/gtkliststore.c (gtk_list_store_insert_before): handle case
+ where sibling == iter
+ (gtk_list_store_insert_after): handle case where sibling == iter
+
+ * tests/testtreeview.c (run_automated_tests): fairly lame basic
+ automated tests for ListStore, TreeStore
+
+ * gtk/gtkliststore.c (gtk_list_store_remove): update tail pointer
+ (gtk_list_store_insert): update tail pointer, and fix it to work
+ (gtk_list_store_insert_before): update tail pointer, and fix it to work
+ (gtk_list_store_append): use tail to be faster
+ (gtk_list_store_prepend): fix it, update tail pointer
+ (gtk_list_store_insert_after): fix it, update tail pointer
+
+ * gtk/gtkliststore.h (struct _GtkListStore): add tail pointer for
+ the list
+
2001-01-09 Havoc Pennington <hp@redhat.com>
* gtk/gtklabel.c (gtk_label_expose): don't draw if label->layout
gtk_list_store_init (GtkListStore *list_store)
{
list_store->root = NULL;
+ list_store->tail = NULL;
list_store->stamp = g_random_int ();
}
va_end (var_args);
}
+static GSList*
+remove_link_saving_prev (GSList *list,
+ GSList *link,
+ GSList **prevp)
+{
+ GSList *tmp;
+ GSList *prev;
+
+ prev = NULL;
+ tmp = list;
+
+ while (tmp)
+ {
+ if (tmp == link)
+ {
+ if (prev)
+ prev->next = tmp->next;
+ if (list == tmp)
+ list = list->next;
+
+ tmp->next = NULL;
+ break;
+ }
+
+ prev = tmp;
+ tmp = tmp->next;
+ }
+
+ *prevp = prev;
+
+ return list;
+}
+
void
gtk_list_store_remove (GtkListStore *list_store,
GtkTreeIter *iter)
g_return_if_fail (list_store != NULL);
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
-
+ g_return_if_fail (iter->user_data != NULL);
+
if (G_SLIST (iter->user_data)->data)
_gtk_tree_data_list_free ((GtkTreeDataList *) G_SLIST (iter->user_data)->data,
list_store->column_headers);
path = gtk_list_store_get_path (GTK_TREE_MODEL (list_store), iter);
- list_store->root = g_slist_remove_link (G_SLIST (list_store->root),
- G_SLIST (iter->user_data));
+
+ {
+ GSList *prev = NULL;
+
+ list_store->root = remove_link_saving_prev (G_SLIST (list_store->root),
+ G_SLIST (iter->user_data),
+ &prev);
+
+ if (iter->user_data == list_store->tail)
+ list_store->tail = prev;
+ }
+
list_store->stamp ++;
gtk_signal_emit_by_name (GTK_OBJECT (list_store),
"deleted",
gtk_tree_path_free (path);
}
+static void
+insert_after (GtkListStore *list_store,
+ GSList *sibling,
+ GSList *new_list)
+{
+ g_return_if_fail (sibling != NULL);
+ g_return_if_fail (new_list != NULL);
+
+ /* insert new node after list */
+ new_list->next = sibling->next;
+ sibling->next = new_list;
+
+ /* if list was the tail, the new node is the new tail */
+ if (sibling == list_store->tail)
+ list_store->tail = new_list;
+}
+
void
gtk_list_store_insert (GtkListStore *list_store,
GtkTreeIter *iter,
{
GSList *list;
GtkTreePath *path;
-
+ GSList *new_list;
+
g_return_if_fail (list_store != NULL);
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL);
- g_return_if_fail (position < 0);
+ g_return_if_fail (position >= 0);
if (position == 0)
{
return;
}
- iter->stamp = list_store->stamp;
- iter->user_data = g_slist_alloc ();
+ new_list = g_slist_alloc ();
list = g_slist_nth (G_SLIST (list_store->root), position - 1);
- if (list)
+
+ if (list == NULL)
{
- G_SLIST (iter->user_data)->next = list->next;
- list->next = G_SLIST (iter->user_data)->next;
+ g_warning ("%s: position %d is off the end of the list\n", G_STRLOC, position);
+ return;
}
+
+ insert_after (list_store, list, new_list);
+
+ iter->stamp = list_store->stamp;
+ iter->user_data = new_list;
+
path = gtk_tree_path_new ();
gtk_tree_path_append_index (path, position);
gtk_signal_emit_by_name (GTK_OBJECT (list_store),
GtkTreeIter *sibling)
{
GtkTreePath *path;
- GSList *list, *prev;
+ GSList *list, *prev, *new_list;
gint i = 0;
g_return_if_fail (list_store != NULL);
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
g_return_if_fail (iter != NULL);
- g_return_if_fail (G_SLIST (iter)->next == NULL);
if (sibling == NULL)
{
gtk_list_store_append (list_store, iter);
return;
}
-
- iter->stamp = list_store->stamp;
- iter->user_data = g_slist_alloc ();
+
+ new_list = g_slist_alloc ();
prev = list = list_store->root;
while (list && list != sibling->user_data)
list = list->next;
i++;
}
+
+ if (list != sibling->user_data)
+ {
+ g_warning ("%s: sibling iterator invalid? not found in the list", G_STRLOC);
+ return;
+ }
+
+ /* if there are no nodes, we become the list tail, otherwise we
+ * are inserting before any existing nodes so we can't change
+ * the tail
+ */
+
+ if (list_store->root == NULL)
+ list_store->tail = new_list;
if (prev)
{
- prev->next = iter->user_data;
+ new_list->next = prev->next;
+ prev->next = new_list;
}
else
{
- G_SLIST (iter->user_data)->next = list_store->root;
- list_store->root = iter->user_data;
+ new_list->next = list_store->root;
+ list_store->root = new_list;
}
+ iter->stamp = list_store->stamp;
+ iter->user_data = new_list;
+
path = gtk_tree_path_new ();
gtk_tree_path_append_index (path, i);
gtk_signal_emit_by_name (GTK_OBJECT (list_store),
GtkTreeIter *sibling)
{
GtkTreePath *path;
- GSList *list;
+ GSList *list, *new_list;
gint i = 0;
g_return_if_fail (list_store != NULL);
g_return_if_fail (GTK_IS_LIST_STORE (list_store));
- g_return_if_fail (iter == NULL);
+ g_return_if_fail (iter != NULL);
if (sibling)
g_return_if_fail (sibling->stamp == list_store->stamp);
for (list = list_store->root; list && list != sibling->user_data; list = list->next)
i++;
- g_return_if_fail (list != NULL);
+ g_return_if_fail (list == sibling->user_data);
- iter->stamp = list_store->stamp;
- iter->user_data = g_slist_alloc ();
-
- G_SLIST (iter->user_data)->next = G_SLIST (sibling->user_data)->next;
- G_SLIST (sibling)->next = G_SLIST (iter);
+ new_list = g_slist_alloc ();
+ insert_after (list_store, list, new_list);
+
+ iter->stamp = list_store->stamp;
+ iter->user_data = new_list;
+
path = gtk_tree_path_new ();
gtk_tree_path_append_index (path, i);
gtk_signal_emit_by_name (GTK_OBJECT (list_store),
iter->stamp = list_store->stamp;
iter->user_data = g_slist_alloc ();
+ if (list_store->root == NULL)
+ list_store->tail = iter->user_data;
+
G_SLIST (iter->user_data)->next = G_SLIST (list_store->root);
list_store->root = iter->user_data;
GtkTreeIter *iter)
{
GtkTreePath *path;
- GSList *list, *prev;
gint i = 0;
g_return_if_fail (list_store != NULL);
iter->stamp = list_store->stamp;
iter->user_data = g_slist_alloc ();
- prev = list = list_store->root;
- while (list)
- {
- prev = list;
- list = list->next;
- i++;
- }
-
- if (prev)
- prev->next = iter->user_data;
+ if (list_store->tail)
+ list_store->tail->next = iter->user_data;
else
list_store->root = iter->user_data;
+ list_store->tail = iter->user_data;
+
path = gtk_tree_path_new ();
gtk_tree_path_append_index (path, i);
gtk_signal_emit_by_name (GTK_OBJECT (list_store),
/*< private >*/
gint stamp;
gpointer root;
+ GSList *tail;
gint n_columns;
GType *column_headers;
};
return TRUE;
}
+/**
+ * gtk_tree_model_get_first:
+ * @tree_model: a #GtkTreeModel
+ * @iter: iterator to initialize
+ *
+ * Initialized @iter with the first iterator in the tree (the one at the
+ * root path) and returns %TRUE, or returns %FALSE if there are no
+ * iterable locations in the model (i.e. the tree is empty).
+ *
+ * Return value: %TRUE if @iter was initialized
+ **/
+gboolean
+gtk_tree_model_get_first (GtkTreeModel *tree_model,
+ GtkTreeIter *iter)
+{
+ gboolean retval;
+ GtkTreePath *path;
+
+ g_return_val_if_fail (GTK_IS_TREE_MODEL (tree_model), FALSE);
+ g_return_val_if_fail (iter != NULL, FALSE);
+
+ path = gtk_tree_path_new_root ();
+
+ retval = gtk_tree_model_get_iter (tree_model, iter, path);
+
+ gtk_tree_path_free (path);
+
+ return retval;
+}
+
/**
* gtk_tree_model_get_path:
* @tree_model: A #GtkTreeModel.
gboolean gtk_tree_model_get_iter (GtkTreeModel *tree_model,
GtkTreeIter *iter,
GtkTreePath *path);
+gboolean gtk_tree_model_get_first (GtkTreeModel *tree_model,
+ GtkTreeIter *iter);
GtkTreePath *gtk_tree_model_get_path (GtkTreeModel *tree_model,
GtkTreeIter *iter);
void gtk_tree_model_get_value (GtkTreeModel *tree_model,
g_return_val_if_fail (tree_model != NULL, NULL);
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), NULL);
g_return_val_if_fail (iter != NULL, NULL);
- g_return_val_if_fail (GTK_TREE_STORE (tree_model)->stamp == iter->stamp, NULL);
+
if (iter->user_data == NULL)
return NULL;
+ g_assert (G_NODE (iter->user_data)->parent != NULL);
+
if (G_NODE (iter->user_data)->parent == G_NODE (GTK_TREE_STORE (tree_model)->root))
{
retval = gtk_tree_path_new ();
g_return_if_fail (tree_model != NULL);
g_return_if_fail (GTK_IS_TREE_STORE (tree_model));
g_return_if_fail (iter != NULL);
- g_return_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp);
g_return_if_fail (column < GTK_TREE_STORE (tree_model)->n_columns);
list = G_NODE (iter->user_data)->data;
g_return_val_if_fail (tree_model != NULL, FALSE);
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
- g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, FALSE);
return G_NODE (iter->user_data)->children != NULL;
}
g_return_val_if_fail (tree_model != NULL, 0);
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), 0);
- if (iter)
- g_return_val_if_fail (iter->stamp == GTK_TREE_STORE (tree_model)->stamp, 0);
if (iter == NULL)
node = G_NODE (GTK_TREE_STORE (tree_model)->root)->children;
g_return_val_if_fail (tree_model != NULL, FALSE);
g_return_val_if_fail (GTK_IS_TREE_STORE (tree_model), FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
- if (parent)
- g_return_val_if_fail (parent->stamp == GTK_TREE_STORE (tree_model)->stamp, FALSE);
if (parent == NULL)
parent_node = GTK_TREE_STORE (tree_model)->root;
GtkTreeIter *iter,
GtkTreeIter *child)
{
+ g_assert (G_NODE (child->user_data)->parent != NULL);
+
iter->stamp = GTK_TREE_STORE (tree_model)->stamp;
iter->user_data = G_NODE (child->user_data)->parent;
if (iter->user_data == GTK_TREE_STORE (tree_model)->root)
{
iter->stamp = 0;
+ iter->user_data = NULL;
return FALSE;
}
parent = G_NODE (iter->user_data)->parent;
+ g_assert (parent != NULL);
+
if (G_NODE (iter->user_data)->data)
_gtk_tree_data_list_free ((GtkTreeDataList *) G_NODE (iter->user_data)->data,
model->column_headers);
if (parent != G_NODE (model->root) && parent->children == NULL)
{
gtk_tree_path_up (path);
+
gtk_signal_emit_by_name (GTK_OBJECT (model),
"child_toggled",
path,
gint position)
{
GtkTreePath *path;
-
+
g_return_if_fail (model != NULL);
g_return_if_fail (GTK_IS_TREE_STORE (model));
GtkTreeIter *sibling)
{
GtkTreePath *path;
- GNode *parent_node = NULL;
-
+ GNode *parent_node = NULL;
+ GNode *new_node;
+
g_return_if_fail (model != NULL);
g_return_if_fail (GTK_IS_TREE_STORE (model));
g_return_if_fail (iter != NULL);
- if (parent != NULL)
- g_return_if_fail (parent->stamp == model->stamp);
- if (sibling != NULL)
- g_return_if_fail (sibling->stamp == model->stamp);
- iter->stamp = model->stamp;
- iter->user_data = g_node_new (NULL);
+ new_node = g_node_new (NULL);
if (parent == NULL && sibling == NULL)
parent_node = model->root;
else if (parent == NULL)
parent_node = G_NODE (sibling->user_data)->parent;
- else
+ else if (sibling == NULL)
parent_node = G_NODE (parent->user_data);
+ else
+ {
+ g_return_if_fail (G_NODE (sibling->user_data)->parent ==
+ G_NODE (parent->user_data));
+ parent_node = G_NODE (parent->user_data);
+ }
g_node_insert_before (parent_node,
sibling ? G_NODE (sibling->user_data) : NULL,
- G_NODE (iter->user_data));
+ new_node);
+ iter->stamp = model->stamp;
+ iter->user_data = new_node;
+
path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
gtk_signal_emit_by_name (GTK_OBJECT (model),
"inserted",
{
GtkTreePath *path;
GNode *parent_node;
-
+ GNode *new_node;
+
g_return_if_fail (model != NULL);
g_return_if_fail (GTK_IS_TREE_STORE (model));
g_return_if_fail (iter != NULL);
- if (parent != NULL)
- g_return_if_fail (parent->stamp == model->stamp);
- if (sibling != NULL)
- g_return_if_fail (sibling->stamp == model->stamp);
- iter->stamp = model->stamp;
- iter->user_data = g_node_new (NULL);
+ new_node = g_node_new (NULL);
if (parent == NULL && sibling == NULL)
parent_node = model->root;
else if (parent == NULL)
parent_node = G_NODE (sibling->user_data)->parent;
- else
+ else if (sibling == NULL)
parent_node = G_NODE (parent->user_data);
+ else
+ {
+ g_return_if_fail (G_NODE (sibling->user_data)->parent ==
+ G_NODE (parent->user_data));
+ parent_node = G_NODE (parent->user_data);
+ }
+
g_node_insert_after (parent_node,
sibling ? G_NODE (sibling->user_data) : NULL,
- G_NODE (iter->user_data));
-
+ new_node);
+
+ iter->stamp = model->stamp;
+ iter->user_data = new_node;
+
path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), iter);
gtk_signal_emit_by_name (GTK_OBJECT (model),
"inserted",
GtkTreeIter *parent)
{
GNode *parent_node;
-
+
g_return_if_fail (model != NULL);
g_return_if_fail (GTK_IS_TREE_STORE (model));
g_return_if_fail (iter != NULL);
- if (parent != NULL)
- g_return_if_fail (parent->stamp == model->stamp);
if (parent == NULL)
parent_node = model->root;
else
parent_node = parent->user_data;
-
- iter->stamp = model->stamp;
- iter->user_data = g_node_new (NULL);
-
+
if (parent_node->children == NULL)
{
GtkTreePath *path;
-
- g_node_prepend (parent_node, G_NODE (iter->user_data));
-
+
+ iter->stamp = model->stamp;
+ iter->user_data = g_node_new (NULL);
+
+ g_node_prepend (parent_node, iter->user_data);
+
if (parent_node != model->root)
{
path = gtk_tree_store_get_path (GTK_TREE_MODEL (model), parent);
g_return_if_fail (model != NULL);
g_return_if_fail (GTK_IS_TREE_STORE (model));
g_return_if_fail (iter != NULL);
- if (parent != NULL)
- g_return_if_fail (parent->stamp == model->stamp);
if (parent == NULL)
parent_node = model->root;
}
}
-void
-gtk_tree_store_get_root_iter (GtkTreeStore *model,
- GtkTreeIter *iter)
-{
- g_return_if_fail (model != NULL);
- g_return_if_fail (GTK_IS_TREE_STORE (model));
- g_return_if_fail (iter != NULL);
-
- iter->stamp = model->stamp;
- iter->user_data = G_NODE (model->root)->children;
-}
-
-
gboolean
gtk_tree_store_is_ancestor (GtkTreeStore *model,
GtkTreeIter *iter,
g_return_val_if_fail (GTK_IS_TREE_STORE (model), FALSE);
g_return_val_if_fail (iter != NULL, FALSE);
g_return_val_if_fail (descendant != NULL, FALSE);
- g_return_val_if_fail (iter->stamp == model->stamp, FALSE);
- g_return_val_if_fail (descendant->stamp == model->stamp, FALSE);
return g_node_is_ancestor (G_NODE (iter->user_data),
G_NODE (descendant->user_data));
g_return_val_if_fail (model != NULL, 0);
g_return_val_if_fail (GTK_IS_TREE_STORE (model), 0);
g_return_val_if_fail (iter != NULL, 0);
- g_return_val_if_fail (iter->stamp == model->stamp, 0);
return g_node_depth (G_NODE (iter->user_data)) - 1;
}
void gtk_tree_store_append (GtkTreeStore *tree_store,
GtkTreeIter *iter,
GtkTreeIter *parent);
-void gtk_tree_store_get_root_iter (GtkTreeStore *tree_store,
- GtkTreeIter *iter);
gboolean gtk_tree_store_is_ancestor (GtkTreeStore *tree_store,
GtkTreeIter *iter,
GtkTreeIter *descendant);
* Automated testing
*/
+static void
+treestore_torture_recurse (GtkTreeStore *store,
+ GtkTreeIter *root,
+ gint depth)
+{
+ GtkTreeModel *model;
+ gint i;
+ GtkTreeIter iter;
+
+ model = GTK_TREE_MODEL (store);
+
+ if (depth > 2)
+ return;
+
+ ++depth;
+
+ gtk_tree_store_append (store, &iter, root);
+
+ gtk_tree_model_iter_children (model, &iter, root);
+
+ i = 0;
+ while (i < 100)
+ {
+ gtk_tree_store_append (store, &iter, root);
+ ++i;
+ }
+
+ while (gtk_tree_model_iter_children (model, &iter, root))
+ gtk_tree_store_remove (store, &iter);
+
+ gtk_tree_store_append (store, &iter, root);
+
+ /* inserts before last node in tree */
+ i = 0;
+ while (i < 100)
+ {
+ gtk_tree_store_insert_before (store, &iter, root, &iter);
+ ++i;
+ }
+
+ /* inserts after the node before the last node */
+ i = 0;
+ while (i < 100)
+ {
+ gtk_tree_store_insert_after (store, &iter, root, &iter);
+ ++i;
+ }
+
+ /* inserts after the last node */
+ gtk_tree_store_append (store, &iter, root);
+
+ i = 0;
+ while (i < 100)
+ {
+ gtk_tree_store_insert_after (store, &iter, root, &iter);
+ ++i;
+ }
+
+ /* remove everything again */
+ while (gtk_tree_model_iter_children (model, &iter, root))
+ gtk_tree_store_remove (store, &iter);
+
+
+ /* Prepends */
+ gtk_tree_store_prepend (store, &iter, root);
+
+ i = 0;
+ while (i < 100)
+ {
+ gtk_tree_store_prepend (store, &iter, root);
+ ++i;
+ }
+
+ /* remove everything again */
+ while (gtk_tree_model_iter_children (model, &iter, root))
+ gtk_tree_store_remove (store, &iter);
+
+ gtk_tree_store_append (store, &iter, root);
+ gtk_tree_store_append (store, &iter, root);
+ gtk_tree_store_append (store, &iter, root);
+ gtk_tree_store_append (store, &iter, root);
+
+ while (gtk_tree_model_iter_children (model, &iter, root))
+ {
+ treestore_torture_recurse (store, &iter, depth);
+ gtk_tree_store_remove (store, &iter);
+ }
+}
+
static void
run_automated_tests (void)
{
+ g_print ("Running automated tests...\n");
+
/* FIXME TreePath basic verification */
- /* FIXME consistency checks on the models */
-
+ /* FIXME generic consistency checks on the models */
+
+ {
+ /* Make sure list store mutations don't crash anything */
+ GtkListStore *store;
+ GtkTreeModel *model;
+ gint i;
+ GtkTreeIter iter;
+
+ store = gtk_list_store_new_with_types (1, G_TYPE_INT);
+
+ model = GTK_TREE_MODEL (store);
+
+ i = 0;
+ while (i < 100)
+ {
+ gtk_list_store_append (store, &iter);
+ ++i;
+ }
+
+ while (gtk_tree_model_get_first (model, &iter))
+ gtk_list_store_remove (store, &iter);
+
+ gtk_list_store_append (store, &iter);
+
+ /* inserts before last node in list */
+ i = 0;
+ while (i < 100)
+ {
+ gtk_list_store_insert_before (store, &iter, &iter);
+ ++i;
+ }
+
+ /* inserts after the node before the last node */
+ i = 0;
+ while (i < 100)
+ {
+ gtk_list_store_insert_after (store, &iter, &iter);
+ ++i;
+ }
+
+ /* inserts after the last node */
+ gtk_list_store_append (store, &iter);
+
+ i = 0;
+ while (i < 100)
+ {
+ gtk_list_store_insert_after (store, &iter, &iter);
+ ++i;
+ }
+
+ /* remove everything again */
+ while (gtk_tree_model_get_first (model, &iter))
+ gtk_list_store_remove (store, &iter);
+
+
+ /* Prepends */
+ gtk_list_store_prepend (store, &iter);
+
+ i = 0;
+ while (i < 100)
+ {
+ gtk_list_store_prepend (store, &iter);
+ ++i;
+ }
+
+ /* remove everything again */
+ while (gtk_tree_model_get_first (model, &iter))
+ gtk_list_store_remove (store, &iter);
+
+ g_object_unref (G_OBJECT (store));
+ }
+
+ {
+ /* Make sure tree store mutations don't crash anything */
+ GtkTreeStore *store;
+
+ store = gtk_tree_store_new_with_types (1, G_TYPE_INT);
+
+ treestore_torture_recurse (store, NULL, 0);
+
+ g_object_unref (G_OBJECT (store));
+ }
+
+ g_print ("Passed.\n");
}